package cn.abcsys.cloud.devops.web.util;



import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.io.IOUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.log4j.Logger;
import org.springframework.util.StringUtils;
import net.sf.json.JSONObject;


/**
 * 通用的HTTP请求客户端 主要有post,get,doPost和doGet四个方法，
 * 
 * @author mingwei.dmw
 *
 */
public class HttpClient {

	private static Logger logger = Logger.getLogger(HttpClient.class);
	private static final int TIME_OUT = 1000 * 60;
	private static final String SUCCESS = "success";
	private static final String MESSAGE = "message";
	private static CloseableHttpResponse response = null;
//	private static String responseContent = null;

	/**
	 * http的Post方法
	 * 
	 * @param param
	 *            请求参数
	 * @param url
	 *            请求路径
	 * @return 返回的response，异常情况时返回空
	 */
	public static Map<String, Object> post(JSONObject param, String url) {
		Map<String, Object> map=new HashMap<String, Object>();
		
		CloseableHttpClient httpclient = HttpClients.createDefault();
		HttpPost httpPost = new HttpPost(url);
		RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(TIME_OUT).setConnectTimeout(TIME_OUT)
				.build();// 设置请求和传输超时时间
		httpPost.setConfig(requestConfig);
		logger.info("URL:" + url + "\nParam:" + param);
		logger.info("INIT PARAMS");
		if (null == param || param.isEmpty()) {
			logger.warn("NO PARAM TO POST!!!");
		} else {
			StringEntity entity = new StringEntity(param.toString(), "utf-8");
			entity.setContentEncoding("UTF-8");
			entity.setContentType("application/json");
			httpPost.setEntity(entity);
		}
		try {
			logger.info("EXECUTE...");
			CloseableHttpResponse response = httpclient.execute(httpPost);
			HttpEntity entity = response.getEntity();
			String content = IOUtils.toString(entity.getContent(),"UTF-8");
			content = new String(content.getBytes(), "UTF-8");
			logger.info("RESPONSE:" + content);
			logger.debug("GET RESPONSE STATUS AND PARSE IT");
			int status = response.getStatusLine().getStatusCode();
			logger.info("RESPONSE STATUS :" + status);
			if (200 == status) {
				logger.info("SUCCESS RESPONSE !");
				map.put("success", true);
				map.put("responseContent", content);
			} else {
				map.put("success", false);
				map.put("message", " http response http code status is "+status);
				logger.warn("FAILED RESPONSE!!");
			}
			logger.debug("CLOSE RESPONSE");
			response.close();
		} catch (Exception e) {
			logger.error("OCCUR AN Exception :\n", e);
			map.put("success", false);
			map.put("message", e.getMessage());
		} finally {
			logger.info("CLOSE THE HTTPCLIENT");
			try {
				httpclient.close();
			} catch (IOException e) {
				logger.error("CLOSE HTTPCLIENT OCCUR AN IOException :\n", e);
			}
		}
		logger.info("METHOD OVER!!");
		return map;
	}

	/**
	 * Get方法
	 * 
	 * @param param
	 *            请求参数
	 * @param url
	 *            请求路径
	 * @return 返回的response，异常情况时返回null
	 */
	public static Map<String, Object> get(Map<String, String> param, String url) {
		Map<String, Object> map=new HashMap<String, Object>();
		
		logger.debug("START TO DOGET METHOD...");
		CloseableHttpClient httpclient = HttpClients.createDefault();
		logger.info("URL:" + url + "\nParam:" + param);
		try {
			logger.info("INIT PARAMS");
			if (null == param || param.isEmpty()) {
				logger.info("NO PARAM TO GET!!!");
			} else {
				List<NameValuePair> parameters = new ArrayList<NameValuePair>();
				for (String key : param.keySet()) {
					parameters.add(new BasicNameValuePair(key, param.get(key)));
				}
				String params = URLEncodedUtils.format(parameters, "UTF-8");
				logger.debug("PARAM IS :" + params);
				url = url + "?" + params;
			}
			HttpGet httpGet = new HttpGet(url);
			RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(TIME_OUT).setConnectTimeout(TIME_OUT)
					.build();// 设置请求和传输超时时间
			httpGet.setConfig(requestConfig);
			logger.info("EXECUTE...");
			CloseableHttpResponse response = httpclient.execute(httpGet);
			HttpEntity entity = response.getEntity();
			String content = IOUtils.toString(entity.getContent(),"UTF-8");
			logger.info("RESPONSE:" + content);
			logger.debug("GET RESPONSE STATUS AND PARSE IT");
			int status = response.getStatusLine().getStatusCode();
			logger.info("RESPONSE STATUS IS :" + status);
			if (200 == status) {
				logger.info("SUCCESS RESPONSE !");
				map.put("success", true);
				map.put("responseContent", content);
			} else {
				map.put("success", false);
				map.put("message", " http response http code status is "+status);
				logger.warn("FAILED RESPONSE!!");
			}
			logger.info("CLOSE RESPONSE");
			response.close();
		}catch (Exception e) {
			logger.error("OCCUR AN Exception :\n", e);
			map.put("success", false);
			map.put("message", e.getMessage());
		} finally {
			logger.info("CLOSE THE HTTPCLIENT");
			try {
				httpclient.close();
			} catch (IOException e) {
				logger.error("CLOSE HTTPCLIENT OCCUR IOException :\n", e);
			}
		}
		
		logger.info("METHOD OVER!!");
		return map;
	}

	/**
	 * http的doPost方法
	 * 
	 * @param param
	 *            请求参数
	 * @param url
	 *            请求路径
	 * @return 返回的response，异常情况时返回空map
	 */
	public static JSONObject doPost(JSONObject param, String url) {
		JSONObject responseMap = new JSONObject();
		 Map<String, Object> response = post(param, url);
		if (!(Boolean)response.get("success")) {
			responseMap.put(SUCCESS, false);
			responseMap.put(MESSAGE,response.get("message"));
			return responseMap;
		}
		try {
			if(!StringUtils.isEmpty((String)response.get("responseContent"))){
				String jsonStr=(String)response.get("responseContent");
				responseMap=JSONObject.fromObject(jsonStr.replaceAll("null", "\"\""));
			}
//			if(!StringUtils.isEmpty((String)response.get("responseContent"))){
//				Object json = new JSONTokener((String)response.get("responseContent")).nextValue();
//				if(json instanceof JSONObject){
//					responseMap.put("response_data", JSONObject.fromObject(json));
//				}else if (json instanceof JSONArray){
//					responseMap.put("response_data", JSONArray.fromObject(json));
//				}else if(json instanceof String){
//					responseMap.put("response_data", json);
//				}
//			}
//			responseMap.put(SUCCESS, "true");
		} catch (Exception e) {
			logger.error("Do post Method error:", e);
			responseMap.put(SUCCESS, false);
			responseMap.put(MESSAGE, "format result data is error!");
			return responseMap;
		}
		return responseMap;
	}

	/**
	 * doGet方法
	 * 
	 * @param param
	 *            请求参数
	 * @param url
	 *            请求路径
	 * @return 返回的response，异常情况时返回空map
	 */
	public static JSONObject doGet(Map<String, String> param, String url) {
		JSONObject responseMap = new JSONObject();
		Map<String, Object> response = get(param, url);
		if (!(Boolean)response.get("success")) {
			responseMap.put(SUCCESS, false);
			responseMap.put(MESSAGE,response.get("message"));
			return responseMap;
		}
		try {
			if(!StringUtils.isEmpty((String)response.get("responseContent"))){
				String jsonStr=(String)response.get("responseContent");
				responseMap=JSONObject.fromObject(jsonStr.replaceAll("null", "\"\""));
			}
//				if(!StringUtils.isEmpty((String)response.get("responseContent"))){
//					Object json = new JSONTokener((String)response.get("responseContent")).nextValue();
//					if(json instanceof JSONObject){
//						responseMap.put("response_data", JSONObject.fromObject(json));
//					}else if (json instanceof JSONArray){
//						responseMap.put("response_data", JSONArray.fromObject(json));
//					}else if(json instanceof String){
//						responseMap.put("response_data", json);
//					}
//				}
//			responseMap.put(SUCCESS, "true");
		} catch (Exception e) {
			logger.error("Do post Method error:", e);
			responseMap.put(SUCCESS, false);
			responseMap.put(MESSAGE, "format result data is error!");
			return responseMap;
		}
		return responseMap;
	}
	
	/**
	 * http的Delete方法
	 * 
	 * @param param
	 *            请求参数
	 * @param url
	 *            请求路径
	 * @return 返回的Result，异常情况时返回{"code":2,"message":"异常信息"}
	 */
	public static JSONObject delete(JSONObject param, String url) {
		JSONObject responseMap = new JSONObject();
		if (!StringUtils.hasText(url)) {
			logger.error("Uri is empty!");
			responseMap.put(SUCCESS, false);
			responseMap.put(MESSAGE, "DELETE ERROR!");
			return responseMap;
			//return new Result((byte)Type.RESULT.FAILED.ordinal(), "Empty URL");
		}
		CloseableHttpClient httpclient = HttpClients.createDefault();
		// 设置请求和传输超时时间
		logger.debug("uri is = {} | params is {}");
		HttpDelete httpDelete = new HttpDelete(url);
		RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(TIME_OUT).setConnectTimeout(TIME_OUT)
				.build();// 设置请求和传输超时时间
		httpDelete.setConfig(requestConfig);
		logger.info("URL:" + url + "\nParam:" + param);
		try {
			logger.info("INIT PARAMS");
			if (null == param || param.isEmpty()) {
				logger.warn("NO PARAM TO POST!!!");
			} else {
				StringEntity entity = new StringEntity(param.toString(), "utf-8");
				entity.setContentEncoding("UTF-8");
				entity.setContentType("application/json");
				((HttpResponse) httpDelete).setEntity(entity);
			}
			logger.info("EXECUTE...");
			CloseableHttpResponse response = httpclient.execute(httpDelete);
			HttpEntity entity = response.getEntity();
			String content = IOUtils.toString(entity.getContent(),"UTF-8");
			logger.info("RESPONSE:" + content);
			try {
				logger.debug("GET RESPONSE STATUS AND PARSE IT");
				int status = response.getStatusLine().getStatusCode();
				logger.info("RESPONSE STATUS IS :" + status);
				if (200 == status) {
					logger.info("SUCCESS RESPONSE !");
//					responseContent = content;
				} else {
					logger.warn("FAILED RESPONSE!!");
				}
			} finally {
				logger.info("CLOSE RESPONSE");
				response.close();
			}
		} catch (IOException e) {
			logger.error("HttpClient Exception:", e);
			responseMap.put(SUCCESS, false);
			responseMap.put(MESSAGE, "IOException!");
			return responseMap;
		} finally {
			try {
				if (null != response) {
					response.close();
					response = null;
				}
				if (null != httpclient) {
					httpclient.close();
				}
			} catch (IOException e) {
				logger.error("HttpClient Get Finally Exception:", e);
			}
		}
		responseMap.put(SUCCESS, true);
		responseMap.put(MESSAGE, "DELETE SUCCESS!");
		return responseMap;
	}


}
